package com.jdy.haoduoai.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;

import com.jdy.haoduoai.LeXiaoXiaoBanApp;
import com.jdy.haoduoai.model.LeMachine;
import com.jdy.haoduoai.model.LeUser;
import com.jdy.haoduoai.util.Tools;
import com.ycsj.goldmedalnewconcept.R;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

//import com.jdy.haoduoai.R;

/**
 * Week View for calendar. It should looks like this(shapes may vary while
 * implementing):
 * 
 * +++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + + + + + + + + +
 * + + + + + + + WeekDayRect + + + + + + + + + + +
 * +++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + + + + + + + + +
 * + + + + + + + + + + + + + + + + + + + + + + + + + + + MonthDayRect + + + + +
 * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 * + + + + + + + +++++++++++++++++++++++++++++++++++++++++++++++++++++ +
 * MonthRect + +++++++++++++++++++++++++++++++++++++++++++++++++++++
 * 
 * @author zp @ 2015-5-7 下午4:08:20
 */
public class WeekCalendar extends View {

  private enum DayShape {
    None,

    Circle,

    Rectangle,
  }

  private enum Orientation {

    None,

    Horizontal,

    Vertical,

  }

  private static final int THREE_DAYS_PER_PAGE = 3;

  private static final int FIVE_DAYS_PER_PAGE = 5;

  private static final int SEVEN_DAYS_PER_PAGE = 7;

  private static final int PADDING_TOP = 10;

  private final int DAYS_PER_PAGE = SEVEN_DAYS_PER_PAGE;

  private int mStrokeColor;

  private int mDayColor;

  private final int mWeekDayColor = 0xff6cc0ff;

  private final int mMonthDayColor = 0xff0c97ff;

  private final int mMonthColor = Color.WHITE;

  private final int mTodayHighlightColor = Color.YELLOW;

  private final int mSelectedHighlightColor = Color.GRAY;

  private int mSelectHighlightColor;

  private int mTodayColor;

  private int mCalendarBackgroundColor;

  private float mRectWidth;

  private float mRectHeight;

  private final DayShape mDayShape = DayShape.Circle;

  @Deprecated
  private float mScreenWidth;

  @Deprecated
  private float mScreenHeight;

  private float mWidthPerRect;

  private float mCalendarWidth;

  private float mCalendarHeight;

  private float mWeekDayRectWidth;

  private float mWeekDayRectHeight;

  private float mMonthDayRectWidth;

  private float mMonthDayRectHeight;

  private float mMonthRectWidth;

  private float mMonthRectHeight;

  private static final float MONTH_DAY_HEIGHT_RATIO = 0.5f;

  private static final float WEEK_DAY_HEIGHT_RATIO = 0.25f;

  private static final float MONTH_HEIGHT_RATIO = 0.25f;

  private final float FIRST_MONTH_DAY_COLUMN_GAP = 8;

  private float mCalendarXOffset;

  private float mCalendarYOffset;

  private final float mWeekDayStrokeWidth = 3;

  private float mWeekDayFontSize = 20 * 2;

  private final float mMonthDayStrokeWidth = 5;

  private final float mCircleStrokeWidth = 5;

  private float mMonthDayFontSize = 20 * 2;

  private float mMonthFontSize = 20 * 2;

  private final float mMonthStrokeWidth = 5;

  private final float mHeaderLineStrokeWidth = 5;

  private final int mHeaderLineColor = Color.WHITE;

  private final String[] WEEK_DAY_NAME_LIST = { "日", "一", "二", "三", "四", "五",
      "六" };

  // private GestureDetector mGestureDetector;

  private final int mFirstDayOfWeek = Calendar.SUNDAY;

  private Calendar mToday;

  public ArrayList<String> taskDays;

  public ArrayList<String> getTaskDays() {
    return taskDays;
  }

  private Calendar mResevedToday;

  private List<MonthDayEvent> mVisibleWeekList;

  private OnMonthDayClickListener mOnMonthDayClickListner;

  private DisplayMetrics mDisplayMetrics;

  public void setTaskDays(ArrayList<String> taskDays) {
    this.taskDays = taskDays;

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    // if (taskDays != null && !taskDays.isEmpty() && mVisibleWeekList != null)
    // {
    // for (MonthDayEvent ee : mVisibleWeekList) {
    // String strDate = sdf.format(ee.Cal.getTime());
    // if (taskDays.contains(strDate)) {
    // ee.hasTask = true;
    // }
    //
    // if (mBaby != null && strDate.compareTo(mBaby.dob) < 0) {
    // ee.isGrayDate = true;
    // }
    //
    // }
    // }

    if (Tools.isNotEmpty(mVisibleWeekList)) {
      for (MonthDayEvent ee : mVisibleWeekList) {
        String strDate = sdf.format(ee.Cal.getTime());

        if (taskDays != null && !taskDays.isEmpty()) {
          if (taskDays.contains(strDate)) {
            ee.hasTask = true;
          }
        }

        if (mBaby != null && strDate.compareTo(mBaby.dob) < 0) {
          ee.isGrayDate = true;
        }

      }
    }

    invalidate();
  }

  public DisplayMetrics getmDisplayMetrics() {
    return mDisplayMetrics;
  }

  public void setmDisplayMetrics(DisplayMetrics mDisplayMetrics) {
    this.mDisplayMetrics = mDisplayMetrics;

    updateTextSize();
  }

  public void setOnMonthDayClickListner(OnMonthDayClickListener omdcl) {
    this.mOnMonthDayClickListner = omdcl;
  }

  private LeMachine mBaby;

  public WeekCalendar(Context context) {
    this(context, null);
    // TODO Auto-generated constructor stub
    // initGestureDetector(context);
    init();
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    this.mScreenWidth = metrics.widthPixels;
    this.mScreenHeight = metrics.heightPixels;
  }

  public WeekCalendar(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
    // TODO Auto-generated constructor stub
    // initGestureDetector(context);
    init();
  }

  public WeekCalendar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub
    // initGestureDetector(context);
    init();
  }

  // private void initGestureDetector(Context context) {
  // this.mGestureDetector = new GestureDetector(context, new GestureListener()
  // {
  // @Override
  // public void onSwipeLeft() {
  // mVisibleWeekList = getNeighborWeekList(true);
  // }
  //
  // @Override
  // public void onSwipeRight() {
  // mVisibleWeekList = getNeighborWeekList(false);
  // }
  //
  // @Override
  // public void onSwipeTop() {
  //
  // mVisibleWeekList = getNeighborMonthWeekList(true);
  // }
  //
  // @Override
  // public void onSwipeBottom() {
  //
  // mVisibleWeekList = getNeighborMonthWeekList(false);
  // }
  //
  // });
  // }

  private void init() {
    this.mToday = Calendar.getInstance();
    this.mResevedToday = (Calendar) this.mToday.clone();

    LeUser lu = LeXiaoXiaoBanApp.getInstance().getUser();

    if (Tools.isNotEmpty(lu)) {
      mBaby = lu.machine;
    }

    bmpComplete = BitmapFactory.decodeResource(getResources(), R.drawable.aa);
  }

  private List<MonthDayEvent> getCurrentWeek() {
    List<MonthDayEvent> currentWeekList = new ArrayList<MonthDayEvent>();
    Calendar reservedCal = (Calendar) this.mToday.clone();
    reservedCal.set(Calendar.DAY_OF_WEEK, reservedCal.getFirstDayOfWeek());
    for (int i = 0; i < 7; i++) {
      MonthDayEvent mde = new MonthDayEvent();
      mde.CurrentDayOfMonth = reservedCal.get(Calendar.DAY_OF_MONTH);
      mde.Cal = (Calendar) reservedCal.clone();
      currentWeekList.add(mde);
      reservedCal.add(Calendar.DAY_OF_MONTH, 1);
    }
    return currentWeekList;
  }

  /**
   * get neighbor week list,true for next week,while false for previous week.
   * 
   * @param next
   * @return
   */
  private List<MonthDayEvent> getNeighborWeekList(boolean next) {
    if (next) {
      this.mToday.add(Calendar.DAY_OF_YEAR, +7);
    } else {
      this.mToday.add(Calendar.DAY_OF_YEAR, -7);
    }
    Calendar resveredDay = (Calendar) this.mToday.clone();

    resveredDay.set(Calendar.DAY_OF_WEEK, resveredDay.getFirstDayOfWeek());
    for (int i = 0; i < 7; i++) {
      mVisibleWeekList.get(i).Cal = (Calendar) resveredDay.clone();
      mVisibleWeekList.get(i).CurrentDayOfMonth = resveredDay
          .get(Calendar.DAY_OF_MONTH);
      mVisibleWeekList.get(i).Selected = false;
      resveredDay.add(Calendar.DAY_OF_MONTH, 1);
    }
    invalidate();
    return mVisibleWeekList;
  }

  private List<MonthDayEvent> getNeighborMonthWeekList(boolean nextMonth) {
    if (nextMonth) {
      this.mToday.add(Calendar.MONTH, +1);
    } else {
      this.mToday.add(Calendar.MONTH, -1);
    }
    Calendar resveredDay = (Calendar) this.mToday.clone();

    resveredDay.set(Calendar.DAY_OF_WEEK, resveredDay.getFirstDayOfWeek());
    for (int i = 0; i < 7; i++) {
      mVisibleWeekList.get(i).Cal = (Calendar) resveredDay.clone();
      mVisibleWeekList.get(i).CurrentDayOfMonth = resveredDay
          .get(Calendar.DAY_OF_MONTH);
      mVisibleWeekList.get(i).Selected = false;
      resveredDay.add(Calendar.DAY_OF_MONTH, 1);
    }
    invalidate();
    return mVisibleWeekList;
  }

  private void initParameters() {
    if (DAYS_PER_PAGE != 0)
      this.mWidthPerRect = this.mCalendarWidth / DAYS_PER_PAGE;
    // Week day
    this.mWeekDayRectWidth = this.mCalendarWidth / DAYS_PER_PAGE;
    this.mWeekDayRectHeight = WEEK_DAY_HEIGHT_RATIO * this.mCalendarHeight;
    // Month day
    this.mMonthDayRectWidth = this.mCalendarWidth / DAYS_PER_PAGE;
    this.mMonthDayRectHeight = MONTH_DAY_HEIGHT_RATIO * this.mCalendarHeight;
    // Month
    this.mMonthRectWidth = this.mCalendarWidth;
    this.mMonthRectHeight = MONTH_HEIGHT_RATIO * this.mCalendarHeight;

    this.mVisibleWeekList = new ArrayList<MonthDayEvent>();
    this.mVisibleWeekList = getCurrentWeek();

    int i = 0;
    float startXOffset = getPaddingLeft();
    float startYOffset = getPaddingTop() + this.mWeekDayRectHeight;
    /* + PADDING_TOP / 2; */
    float rectX = startXOffset + FIRST_MONTH_DAY_COLUMN_GAP;
    float rectY = startYOffset;
    float radius = this.mMonthDayRectWidth < this.mMonthRectHeight ? this.mMonthDayRectWidth
        : this.mMonthDayRectHeight;
    // rectY += Math.abs(this.mMonthDayRectHeight - this.mMonthDayRectWidth);
    // radius = radius / 5 + radius / 14;

    radius = radius / 2;

    float cx = 0;
    float cy = 0;

    for (; i < mVisibleWeekList.size(); i++) {
      cx = rectX + radius;
      cy = rectY + radius;
      rectX += this.mMonthDayRectWidth;
      RectF rect = new RectF(cx - radius / 2 - radius / 5, cy - radius / 2
          - radius / 5, cx + radius / 2 + radius / 5, cy + radius / 2 + radius
          / 5);
      mVisibleWeekList.get(i).eventRectF = rect;
      mVisibleWeekList.get(i).CX = cx;
      mVisibleWeekList.get(i).CY = cy;
      mVisibleWeekList.get(i).Radius = radius;

      if (isSameDay(mVisibleWeekList.get(i).Cal, this.mResevedToday)) {
        currentIndex = i;
      }

    }

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    if (Tools.isNotEmpty(mVisibleWeekList)) {
      for (MonthDayEvent ee : mVisibleWeekList) {
        String strDate = sdf.format(ee.Cal.getTime());

        if (mBaby != null && strDate.compareTo(mBaby.dob) < 0) {
          ee.isGrayDate = true;
        }

      }
    }
  }

  private int lastIndex, currentIndex;

  public int getLastIndex() {
    return lastIndex;
  }

  public void setLastIndex(int index) {
    lastIndex = index;
  }

  public int getCurrentIndex() {
    return currentIndex;
  }

  private void selectOnMonthDayEvent(float x, float y) {

    for (int i = 0; i < mVisibleWeekList.size(); i++) {
      MonthDayEvent mde = mVisibleWeekList.get(i);

      if (mde.isGrayDate) {
        continue;
      }

      mde.Selected = mde.eventRectF.contains(x, y);
      if (mde.Selected && this.mOnMonthDayClickListner != null) {
        mde.weekindex = i;

        currentIndex = i;

        mOnMonthDayClickListner.onMonthDayClick(mde);
      }
    }

    // for (MonthDayEvent mde : mVisibleWeekList) {
    // mde.Selected = mde.eventRectF.contains(x, y);
    // if (mde.Selected && this.mOnMonthDayClickListner != null)
    // mOnMonthDayClickListner.onMonthDayClick(mde);
    // }
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    // boolean result = mGestureDetector.onTouchEvent(event);

    boolean result = false;

    if (!result) {
      if (event.getAction() == MotionEvent.ACTION_DOWN) {
        selectOnMonthDayEvent(event.getX(), event.getY());
        invalidate();
        result = true;
      }
    }
    return result;
  }

  float RATIO;

  private void updateTextSize() {
    if (mDisplayMetrics != null) {
      int screenWidth = mDisplayMetrics.widthPixels;
      int screenHeight = mDisplayMetrics.heightPixels;
      float ratioWidth = (float) screenWidth / 1080;
      float ratioHeight = (float) screenHeight / 1920;

      RATIO = Math.min(ratioWidth, ratioHeight);

      mWeekDayFontSize = Math.round(34 * RATIO);
      mMonthDayFontSize = Math.round(54 * RATIO);
      mMonthFontSize = Math.round(40 * RATIO);
    }
  }

  @Override
  public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // drawHeaderLine(canvas);

    drawWeekDayRegion(canvas);

    drawMonthDayRegion(canvas);

    // drawMonthRegion(canvas);

  }

  private void drawHeaderLine(Canvas canvas) {
    float startX = getPaddingLeft();
    float startY = getPaddingTop();
    float stopX = startX + this.mCalendarWidth;
    float stopY = startY;
    Paint paint = new Paint();
    paint.setStrokeWidth(this.mHeaderLineStrokeWidth);
    paint.setColor(this.mHeaderLineColor);
    canvas.drawLine(startX, startY, stopX, stopY, paint);
  }

  /**
   * Draw text in the center of a rectangle.
   * 
   * @param canvas
   * @param text
   * @param paint
   * @param rect
   */
  private void drawTextWithinRect(Canvas canvas, String text, Paint paint,
      RectF rect, boolean considerTextWidth) {
    FontMetricsInt fontMetrics = paint.getFontMetricsInt();
    float baseline = rect.top
        + (rect.bottom - rect.top - fontMetrics.bottom + fontMetrics.top) / 2
        - fontMetrics.top;
    paint.setTextAlign(Paint.Align.CENTER);
    int offset = 0;
    if (considerTextWidth) {
      Rect bounds = new Rect();
      paint.getTextBounds(text, 0, text.length(), bounds);
      int width = bounds.width();
      offset = width / 2;
    }
    canvas.drawText(text, rect.centerX() - offset, baseline, paint);
  }

  /**
   * 
   * @param canvas
   */
  private void drawWeekDayRegion(Canvas canvas) {
    int i = 0;
    float startXOffset = getPaddingLeft();
    float startYOffset = getPaddingTop() + PADDING_TOP;
    float rectX = startXOffset;
    float rectY = startYOffset;
    Paint paint = new Paint();
    paint.setStrokeWidth(this.mWeekDayStrokeWidth);
    paint.setTextSize(this.mWeekDayFontSize);
    paint.setAntiAlias(true);
    paint.setColor(this.mWeekDayColor);
    for (; i < WEEK_DAY_NAME_LIST.length; i++) {
      RectF rect = new RectF(rectX, rectY, rectX + mWeekDayRectWidth, rectY
          + mWeekDayRectHeight);
      rectX += this.mWeekDayRectWidth;
      drawTextWithinRect(canvas, WEEK_DAY_NAME_LIST[i], paint, rect, true);
    }
  }

  private void drawMonthDayRegion(Canvas canvas) {
    int i = 0;
    Paint paint = new Paint();
    paint.setTextSize(this.mMonthDayFontSize);
    paint.setAntiAlias(true);
    Path path = new Path();
    float cx, cy, radius = 0;
    for (; i < mVisibleWeekList.size(); i++) {
      RectF rect = mVisibleWeekList.get(i).eventRectF;
      paint.setStrokeWidth(this.mCircleStrokeWidth);
      if (!mVisibleWeekList.get(i).Selected
          && !isSameDay(mVisibleWeekList.get(i).Cal, this.mResevedToday)) {
        paint.setStyle(Style.STROKE);

        if (mVisibleWeekList.get(i).isGrayDate) {
          paint.setColor(0xffa9a9a9);
        } else {
          paint.setColor(this.mMonthDayColor);
        }

        cx = mVisibleWeekList.get(i).CX;
        cy = mVisibleWeekList.get(i).CY;
        radius = mVisibleWeekList.get(i).Radius;
        // canvas.drawCircle(cx, cy, radius, paint);
        paint.setStyle(Style.FILL);
        paint.setStrokeWidth(this.mMonthDayStrokeWidth);
        drawTextWithinRect(canvas,
            String.valueOf(mVisibleWeekList.get(i).CurrentDayOfMonth), paint,
            rect, false);
      } else if (mVisibleWeekList.get(i).Selected) {
        paint.setStyle(Style.FILL);
        // paint.setColor(this.mSelectedHighlightColor);
        canvas.save();
        float dx = mVisibleWeekList.get(i).CX;
        float dy = mVisibleWeekList.get(i).CY;
        float r = mVisibleWeekList.get(i).Radius + this.mCircleStrokeWidth;

        canvas.translate(dx, dy);

        path.reset();
        // path.addCircle(0, 0, r, Path.Direction.CCW);
        canvas.clipPath(path, Op.REPLACE);
        // canvas.drawPaint(paint);
        canvas.drawPath(path, paint);
        canvas.restore();
        if (mVisibleWeekList.get(i).isGrayDate) {
          paint.setColor(0xffa9a9a9);
        } else {
          paint.setColor(this.mMonthDayColor);
        }
        paint.setStrokeWidth(this.mMonthDayStrokeWidth);
        drawTextWithinRect(canvas,
            String.valueOf(mVisibleWeekList.get(i).CurrentDayOfMonth), paint,
            rect, false);
      } else {
        paint.setStyle(Style.FILL);
        // paint.setColor(this.mTodayHighlightColor);
        canvas.save();

        float dx = mVisibleWeekList.get(i).CX;
        float dy = mVisibleWeekList.get(i).CY;
        float r = mVisibleWeekList.get(i).Radius + this.mCircleStrokeWidth;

        canvas.translate(dx, dy);

        path.reset();
        // path.addCircle(0, 0, r, Path.Direction.CCW);
        canvas.clipPath(path, Op.REPLACE);
        canvas.drawPath(path, paint);
        canvas.restore();
        if (mVisibleWeekList.get(i).isGrayDate) {
          paint.setColor(0xffa9a9a9);
        } else {
          paint.setColor(this.mMonthDayColor);
        }
        paint.setStrokeWidth(this.mMonthDayStrokeWidth);
        drawTextWithinRect(canvas,
            String.valueOf(mVisibleWeekList.get(i).CurrentDayOfMonth), paint,
            rect, false);
      }

      if (bmpComplete != null && mVisibleWeekList.get(i).hasTask) {
        canvas
            .drawBitmap(bmpComplete,
                (mVisibleWeekList.get(i).eventRectF.left + mVisibleWeekList
                    .get(i).eventRectF.right) / 2,
                mVisibleWeekList.get(i).eventRectF.bottom + 6, paint);
      }
    }

    canvas.drawLine(mVisibleWeekList.get(currentIndex).eventRectF.left,
        mVisibleWeekList.get(currentIndex).eventRectF.bottom + 3,
        mVisibleWeekList.get(currentIndex).eventRectF.right,
        mVisibleWeekList.get(currentIndex).eventRectF.bottom + 3, paint);

  }

  private Bitmap bmpComplete;

  private boolean isSameDay(Calendar dayOne, Calendar dayTwo) {
    return dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR)
        && dayOne.get(Calendar.DAY_OF_YEAR) == dayTwo.get(Calendar.DAY_OF_YEAR);
  }

  @SuppressWarnings("unused")
  private void drawMonthRegion(Canvas canvas) {
    int i = 0;
    float startXOffset = getPaddingLeft();
    float startYOffset = getPaddingTop() + this.mWeekDayRectHeight
        + this.mMonthDayRectHeight;
    float rectX = startXOffset;
    float rectY = startYOffset;
    // RectF rect = new RectF(rectX, rectY, rectX + this.mMonthRectWidth, rectY
    // + this.mMonthRectHeight);
    Paint paint = new Paint();
    paint.setStrokeWidth(this.mMonthStrokeWidth);
    paint.setTextSize(this.mMonthFontSize);
    paint.setAntiAlias(true);
    paint.setColor(Color.BLUE);
    // String monthString = String.format("%04d年 %02d月",
    // this.mToday.get(Calendar.YEAR), this.mToday.get(Calendar.MONTH) + 1);
    // drawTextWithinRect(canvas, monthString, paint, rect, false);
    // canvas.drawLine(startX, startY, stopX, stopY, paint);
  }

  @Override
  protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
    super.onSizeChanged(xNew, yNew, xOld, yOld);
    this.mCalendarWidth = xNew;
    this.mCalendarHeight = yNew;
    initParameters();
    this.mScreenWidth = xNew;
    this.mScreenHeight = yNew;
  }

  @Override
  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int desiredWidth = 300;
    int desiredHeight = 280;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    // Measure Width
    if (widthMode == MeasureSpec.EXACTLY) {
      // Must be this size
      width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
      // Can't be bigger than...
      width = Math.min(desiredWidth, widthSize);
    } else {
      // Be whatever you want
      width = desiredWidth;
    }

    // Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
      // Must be this size
      height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
      // Can't be bigger than...
      height = Math.min(desiredHeight, heightSize);
    } else {
      // Be whatever you want
      height = desiredHeight;
    }

    // MUST CALL THIS
    setMeasuredDimension(width, height);
  }

  private class GestureListener extends SimpleOnGestureListener {

    private static final int SWIPE_THRESHOLD = 100;
    private static final int SWIPE_VELOCITY_THRESHOLD = 100;

    @Override
    public boolean onDown(MotionEvent e) {
      return true;
    }

    public void onSwipeRight() {

    }

    public void onSwipeLeft() {

    }

    public void onSwipeTop() {

    }

    public void onSwipeBottom() {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
      boolean result = false;
      try {
        float diffY = e2.getY() - e1.getY();
        float diffX = e2.getX() - e1.getX();
        if (Math.abs(diffX) > Math.abs(diffY)) {
          if (Math.abs(diffX) > SWIPE_THRESHOLD
              && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
            if (diffX > 0) {
              onSwipeRight();
            } else {
              onSwipeLeft();
            }
          }
          result = true;
        } else if (Math.abs(diffY) > SWIPE_THRESHOLD
            && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
          if (diffY > 0) {
            onSwipeBottom();
          } else {
            onSwipeTop();
          }
        }
        result = true;

      } catch (Exception exception) {
        exception.printStackTrace();
      }
      return result;
    }

  }
}
